home *** CD-ROM | disk | FTP | other *** search
- // DO NOT import this into the global namespace, but instead
- // import it into your own namespace wrapper
-
- var EXPORTED_SYMBOLS = ["SCRIPT_MANAGER"];
-
- Components.utils.import("resource://glydo/utils/prototype_xul_1_6_0_3_modified.jsm");
- Components.utils.import("resource://glydo/utils/io.jsm");
- Components.utils.import("resource://glydo/utils/Utils.jsm");
- Components.utils.import("resource://glydo/utils/Prefs.jsm");
- Components.utils.import("resource://glydo/utils/Events.jsm");
- Components.utils.import("resource://glydo/ClientInfo.jsm");
-
- var ScriptManager = Prototype.Class.create(EventSource,{
- initialize: function($super) {
- $super();
- this.remoteResourcesVersion = 0;
- this.remoteResources = {};
- this.localScripts = {};
- this.timedSyncCallback = Prototype.F.bind(this.syncRemoteResources,this);
- this.syncTimer = null;
- this.loadScripts();
- var me = this;
- this.fixedGlobalFunctions = {
- SM_dump: function(s) { me.dump(s); },
- };
- },
-
- getResource: function(name) {
- return this.remoteResources[name];
- },
-
- getScript: function(name) {
- return this.localScripts[name] || this.getResource("scripts/" + name + ".js");
- },
-
- loadScripts: function() {
- var loaded = this.loadRemoteResourcesCache();
- // Start synchronizing with the remote repository
- this.syncRemoteResources();
-
- this.fire("onResourcesUpdated");
- },
-
- loadRemoteResourcesCache: function() {
- var failed = true;
- try {
- // Load remote resources cache
- file = DirIO.get("ProfD");
- file.append("glydo");
- DirIO.create(file);
- file.append("resources");
- DirIO.create(file);
- file.append("remote_resources.json");
-
- var json = FileIO.read(file);
- if (json !== false) {
- var cache = Prototype.S.decodeJSON(json);
- this.remoteResourcesVersion = cache.version;
- this.remoteResources = cache.resources;
- failed = false;
- }
- } catch (ex) {
-
- if (window.Components) {
- Components.utils.reportError(ex);
- }
- }
- if (failed) {
- this.remoteResourcesVersion = 0;
- this.remoteResources = {};
- }
- return !failed;
- },
-
- saveRemoteResourcesCache: function() {
- // Note that multiple simultaneous saves may corrupt
- // the file. We should probably move to a model
- // that is more tolerant to concurrency scenarios.
- // We deal with corrupt files in the load cache
- // method.
- var failed = true;
-
- var contents = Prototype.O.toJSON({
- version: this.remoteResourcesVersion,
- resources: this.remoteResources
- });
-
- try {
- // Save remote resources cache
- var file = DirIO.get("ProfD");
- file.append("glydo");
- DirIO.create(file);
- file.append("resources");
- DirIO.create(file);
- file.append("remote_resources.json");
- FileIO.create(file);
- if (!FileIO.write(file,contents)) {
- throw "Can't store remote resources cache\n";
- }
- failed = false;
- } catch (ex) {
-
- if (window.Components) {
- Components.utils.reportError(ex);
- }
- }
- return !failed;
- },
-
- syncRemoteResources: function() {
- var params = ({
- updated_since: this.remoteResourcesVersion,
- clientVersion: CLIENT_INFO.version
- });
- if (this.syncTimer !== null) {
- Utils.clearTimeout(this.syncTimer);
- this.syncTimer = null;
- }
- this.syncTimer = Utils.setTimeout(this.timedSyncCallback,Prefs.resources_repository_sync_interval_millis);
- new Prototype.Ajax.Request(
- Prefs.resources_repository_url, {
- method: 'get',
- parameters: params,
- onSuccess: Prototype.F.bind(this.onGetRemoteResourcesSuccess,this),
- onFailure: Prototype.F.bind(this.onAjaxFailure,this)
- });
- },
-
- onAjaxFailure: function(response) {
- var reason = response ? response.responseText : "Communication problem";
- if (!reason) {
- reason = "Communication problem";
- }
-
- },
-
- onGetRemoteResourcesSuccess: function(response) {
- if (!response || (response.status == 0)) {
- this.onAjaxFailure(response);
- return;
- }
-
- // We first store the result in memory
- var result = response.responseJSON;
- if (result) {
- var updatedResources = [];
- var newVersion = result.version || 0;
- for (var n in result.updates) {
- if (!Prototype.S.startsWith(n,".")) {
- var o = result.updates[n];
- if (o === null || o === undefined) {
-
- delete this.remoteResources[n];
- } else {
-
- this.remoteResources[n] = o;
- }
- updatedResources.push(n);
- }
- }
-
- this.remoteResourcesVersion = newVersion;
- if (updatedResources.length > 0) {
- this.fire("onResourcesUpdated",updatedResources);
- // We save the remote resources in the local cache
- this.saveRemoteResourcesCache();
- }
- }
- },
-
-
-
-
- getSandbox: function(doc) {
- return new ScriptManager.Sandbox(this,doc);
- },
-
- invoke: function(doc,name,options,callbacks,libs) {
- var sandbox = this.getSandbox(doc);
- sandbox.invoke(name,options,callbacks,libs);
- },
-
- dump: function(s) {
-
- },
- });
-
- ScriptManager.Sandbox = Prototype.Class.create({
- initialize: function(scriptManager,doc) {
- this.scriptManager = scriptManager;
- this.document = doc;
- var unsafeWindow = doc.defaultView;
-
- if (unsafeWindow.wrappedJSObject) {
- unsafeWindow = unsafeWindow.wrappedJSObject;
- }
-
- this.window = new XPCNativeWrapper(unsafeWindow);
- this.sandbox = Components.utils.Sandbox(this.window);
- this.sandbox.window = this.window;
- this.sandbox.unsafeWindow = this.window.wrappedJSObject;
- this.sandbox.document = this.window.document;
- this.sandbox.__proto__ = this.sandbox.window;
- this.sandbox.Func = {};
- this.sandbox.__callbacks = {};
-
- //this.sandbox = new XPCSafeJSObjectWrapper(this.sandbox);
-
- this.imports = {};
- this.importEnv(doc);
- },
-
- exec: function(name) {
- var code = this.scriptManager.getScript(name);
- if (!code) {
- throw new Error("No code for script id '" + name + "'");
- }
- try {
- Components.utils.evalInSandbox(code,this.sandbox);
- } catch (e) {
- var msg = (typeof e == "string") ? e : (e.name + ": " + e.message);
- msg = msg + " (while executing " + name + ")";
- throw new Error(msg,name,0);
- }
- },
-
- importScript: function(name) {
- // If script was already dynamically imported, don't import it again. Otherwise
- // we import it
- var imported = this.imports[name];
- if (imported && imported.type == "dynamic") {
- //
- return;
- }
- // Get code
- var code = this.scriptManager.getScript(name);
- if (!code) {
- if (imported) {
- //
- return;
- }
- throw new Error("No code for script id '" + name + "'");
- }
-
- var escName = name.toSource();
- //
- try {
- Components.utils.evalInSandbox("Func[" + escName + "] = function(options,callbacks){"+code+"};",this.sandbox);
- } catch (e) {
- var msg = (typeof e == "string") ? e : (e.name + ": " + e.message);
- msg = msg + " (while importing " + name + ")";
- throw new Error(msg,name,0);
- }
- this.imports[name] = {
- type: "dynamic"
- };
- },
-
- importBuiltinLibraries: function(libs) {
- for (var l = 0; l < libs.length; ++l) {
- this.importBuiltinLibrary(libs[l]);
- }
- },
-
- importBuiltinLibrary: function(library) {
- for (var name in library) {
- this.importBuiltinScript(name,library[name]);
- }
- },
-
- importBuiltinScript: function(name,func) {
- if (this.imports[name]) {
- //
- return;
- }
- // Import function
- var globName = "__SM_import_" + name.replace(/[^a-zA-Z_0-9]/g,"_");
- var me = this;
- this.sandbox.importFunction(function(options,callbacks) {
- return func(me,options,callbacks);
- },globName);
- var escName = name.toSource();
- //
- Components.utils.evalInSandbox("Func[" + escName + "] = " + globName + ";",this.sandbox);
- this.imports[name] = {
- type: "builtin",
- func: func
- };
- },
-
- importCallbacks: function(callbacks) {
- Components.utils.evalInSandbox("__callbacks = {};",this.sandbox);
- if (callbacks) {
- for (var p in callbacks) {
- var cbname = "__SM_callback_" + p;
- this.sandbox.importFunction(callbacks[p],cbname);
- Components.utils.evalInSandbox("__callbacks[" + p.toSource() + "]=" + cbname + ";\n" + cbname + "=undefined;",this.sandbox);
- }
- }
- },
-
- importEnv: function() {
- this.importFixedFunctions();
- var me = this;
- // The import function imports into the current sandbox
- this.sandbox.importFunction(function(name) {
- me.importScript(name);
- },"SM_import");
- this.sandbox.importFunction(function(name) {
- me.exec(name);
- },"SM_exec");
- // var win = doc.defaultView;
- // var origin = win.location.protocol + "//" + win.location.host;
- // this.sandbox.importFunction(function(eventType,data) {
- // var evt = doc.createEvent("MessageEvents");
- // evt.initMessageEvent(eventType, true, false, data, origin,null,win);
- // win.dispatchEvent(evt);
- // },"SM_message");
- },
-
- importFixedFunctions: function() {
- for (var p in this.scriptManager.fixedGlobalFunctions) {
- this.sandbox.importFunction(this.scriptManager.fixedGlobalFunctions[p],p);
- }
- },
-
- invoke: function(name,options,callbacks,libs) {
- // We only allow JSON-able options to be passed into scripts, for
- // security purposes
- options = options || {};
- var optionsJSON = Prototype.O.toJSON(options);
- if (libs) {
- this.importBuiltinLibraries(libs);
- }
- this.importScript(name);
- this.importCallbacks(callbacks);
- var imported = this.imports[name];
- if (imported.type == "builtin") {
- imported.func(this,options,callbacks);
- } else {
- try {
- Components.utils.evalInSandbox(
- "(function(){return Func[" + name.toSource() + "]((" + optionsJSON + "),__callbacks);})()",
- this.sandbox);
- } catch (e) {
- var msg = (typeof e == "string") ? e : (e.name + ": " + e.message);
- msg = msg + " (while executing " + name + ")";
- throw new Error(msg,name,0);
- }
- }
- },
- });
-
- var SCRIPT_MANAGER = new ScriptManager();
-